#include "CommutativityGenerator.h"
#include "FullSearchEngine.h"

FullSearchEngine::FullSearchEngine(Query *query)
	: SearchEngine("FullSearchEngine", query)
{
}

FullSearchEngine::~FullSearchEngine()
{	
}

void FullSearchEngine::search()
{
	QueryStorage *qs = new QueryStorage();
	int startpos = 0;

	generator = generators.front();

	qs->addQuery(new QueryInfo(query, queryNumber));
	generator->generate(query, qs, startpos, &queryNumber);

	findCosts(qs);

	search(qs, startpos + 1);

	qOut->printOptimizationResults(getName(), min_query, min_cost, (*qs->queries.begin())->cost, timer->getMilliseconds());

	qs->queries.erase(qs->queries.begin());

	delete qs;
}

void FullSearchEngine::search(QueryStorage *qs, int startpos)
{
	if (qs->empty())
	{
		return;
	}

	qOut->printQueries(qs, "output/", getName());

	for (std::vector <QueryInfo *> :: iterator i = qs->queries.begin(); i != qs->queries.end(); i++)
	{
		qOut->printQuery(*i, current);
				
		QueryStorage *qst = new QueryStorage();

		qst->addQuery(*i);	

		bool result = generator->generate((*i)->query, qst, startpos, &queryNumber);
		
		int t = current;
		current = (*i)->number;

		if (result)
		{
			findCosts(qst);

			search(qst, startpos + 1);
		}
		else
		{
			if (++currGenerator >= generators.size())
			{
				--currGenerator;
			}
			else
			{
				generator = generators[currGenerator];
				search(qst, 0);
				generator = generators[--currGenerator];
			}
		}

		qst->queries.erase(qst->queries.begin());
		
		current = t;

		delete qst;
	}
}